# coding=utf-8
'''
Created on Mar 26, 2013

@author: Petko
'''
import unittest
from utils.sententialyzer_client import SententialyzerClient
import json
from urllib2 import HTTPError
from opinion import check_opinion_tree


class CreateOpinionTest(unittest.TestCase):

    sc = SententialyzerClient()
    
    def setUp(self):
        delete_opinions=True
        if delete_opinions:
            self.sc.authorize('moderator1', 'test', 'bopin_r bopin_d')
            result = self.sc.viewListOp('all_base_opinions', 'newest', access_token = self.sc.accessToken)
            page = result['page']
            for op in page:
                self.sc.deleteBaseOp(op['id'])
            
        self.sc.commenterId = 1


    def tearDown(self):
        #result = self.sc.viewListOp('all_base_opinions', 'newest', access_token = self.sc.accessToken)
        #page = result['page']
        
        pass

    def checkAttentions(self, opId, positive = -1, negative = -1):
        op = self.sc.getOpSimple(opId, 'most_positive', max_content_length=4, max_depth=0)
        if positive >= 0:
            self.assertEqual(op['positive'], positive)
        
        if negative >= 0:
            self.assertEqual(op['negative'], negative)
            
    def authAndCreateOp(self, baseOp, parent, evaluation, **kwargs):
        return self.sc.authAndCreateOp(baseOp, parent, evaluation, **kwargs)
    
    
    def test_create_op(self):
        self.sc.authorize('moderator1', 'test', 'bopin_r')
        result = self.sc.viewListOp('all_base_opinions', 'newest', access_token = self.sc.accessToken, max_content_length = 2)
        print json.dumps(result)
        page = result['page']
        if len(page):
            bOpin = page[0]
            opId = bOpin['id']
            scope = opId + ':cr'
            if len(page) > 1:
                scope += ' ' + page[1]['id'] + ':cd'
            
            self.sc.authorize('moderator1', 'test', scope)
            op1 = self.sc.createOp(opId, 'positive', title = 'op1', content = 'op1')
            
            self.sc.createOp(op1['id'], 'positive', title = 'op11', content = 'op11')
            self.sc.createOp(op1['id'], 'negative', title = 'op12', content = 'op12')
            self.sc.createOp(op1['id'], 'negative', title = 'op12', content = 'op12')
            
            op2 = self.sc.createOp(opId, 'positive', title = 'op2', content = 'op2')
            
            self.sc.createOp(op2['id'], 'positive', title = 'op21', content = 'op21')
            self.sc.createOp(op2['id'], 'positive', title = 'op22', content = 'op22')
            
            allOp = self.sc.getOpSimple(opId, 'most_attended', max_content_length=4)
            print json.dumps(allOp)
            
            allOp = self.sc.getOpSimple(opId, 'most_positive', max_content_length=4)
            print json.dumps(allOp)
            
    def test_attentions(self):
        self.sc.authorize('moderator1', 'test', 'bopin_c')
        
        result = self.sc.createBaseOp("attentions test base", "bla bla bla", "moderators:d sent_default_group:rc")
        
        baseOpId = result['id']
        
        op1 = self.authAndCreateOp(baseOpId, baseOpId, 'positive', title = 'op1+', content = 'op plus')
        
        self.checkAttentions(baseOpId, 1)
        
        self.authAndCreateOp(baseOpId, op1['id'], 'positive', title = 'op11+', content = 'op plus')
        
        self.checkAttentions(baseOpId, 2, 0)
        self.checkAttentions(op1['id'], 1, 0)
        
        self.authAndCreateOp(baseOpId, op1['id'], 'positive')
        
        self.checkAttentions(baseOpId, 3, 0)
        self.checkAttentions(op1['id'], 2, 0)
        
        baseOp = self.sc.getOpSimple(baseOpId, 'most_positive', max_content_length=4)
        
        subOp = baseOp['sub_opinions'][0]
        
        self.assertEqual(subOp['positive'], 2)
        
        op2 = self.authAndCreateOp(baseOpId, baseOpId, 'negative', title = 'op2-')
        
        self.checkAttentions(baseOpId, 3, 1)
        
        self.authAndCreateOp(baseOpId, op2['id'], 'positive', title = 'op21+', content = 'op plus')
        
        self.checkAttentions(baseOpId, 3, 2)
        self.checkAttentions(op2['id'], 1, 0)
        
        self.authAndCreateOp(baseOpId, op2['id'], 'positive')
        
        self.checkAttentions(baseOpId, 3, 3)
        self.checkAttentions(op2['id'], 2, 0)
        
        baseOp = self.sc.getOpSimple(baseOpId, 'most_positive', max_content_length=4)
        
        subOp1 = baseOp['sub_opinions'][0]
        
        self.assertEqual(subOp1['title'], 'op1+')
        
        self.assertEqual(subOp1['positive'], 2)
        
        subOp2 = baseOp['sub_opinions'][1]
        
        self.assertEqual(subOp2['title'], 'op2-')
        
        self.assertEqual(subOp2['positive'], 2)
    
    def test_negative_attention(self):
        self.sc.authorize('moderator1', 'test', 'bopin_c')
        
        result = self.sc.createBaseOp("attentions test base", "bla bla bla", "moderators:d sent_default_group:rc")
        
        baseOpId = result['id']
        
        op1 = self.authAndCreateOp(baseOpId, baseOpId, 'negative', title = 'op1-', content = 'op')
        
        self.checkAttentions(baseOpId, 0, 1)
        
        op11 = self.authAndCreateOp(baseOpId, op1['id'], 'positive', title = 'op11-', content = 'op')
        
        self.checkAttentions(baseOpId, 0, 2)
        self.checkAttentions(op1['id'], 1, 0)
        
        op111 = self.authAndCreateOp(baseOpId, op11['id'], 'positive', title = 'op111', content = 'op')
        
        self.checkAttentions(baseOpId, 0, 3)
        self.checkAttentions(op1['id'], 2, 0)
        self.checkAttentions(op11['id'], 1, 0)
        
        self.authAndCreateOp(baseOpId, op111['id'], 'positive', title = 'op1111', content = 'op')
        
        self.checkAttentions(baseOpId, 0, 4)
        self.checkAttentions(op1['id'], 3, 0)
        self.checkAttentions(op11['id'], 2, 0)
        self.checkAttentions(op111['id'], 1, 0)
        
        op1112 = self.authAndCreateOp(baseOpId, op111['id'], 'negative', title = 'op1112', content = 'op')
        
        self.checkAttentions(baseOpId, 1, 4)
        self.checkAttentions(op1['id'], 3, 1)
        self.checkAttentions(op11['id'], 2, 1)
        self.checkAttentions(op111['id'], 1, 1)
        
        self.authAndCreateOp(baseOpId, op1112['id'], 'negative', title = 'op11121', content = 'op')
        self.checkAttentions(baseOpId, 1, 5)
        self.checkAttentions(op1['id'], 4, 1)
        self.checkAttentions(op11['id'], 3, 1)
        self.checkAttentions(op111['id'], 2, 1)
        self.checkAttentions(op1112['id'], 0, 1)
    
    def test_neutral_attention(self):
        self.sc.authorize('moderator1', 'test', 'bopin_c')
        
        result = self.sc.createBaseOp("attentions test base", "bla bla bla", "moderators:d sent_default_group:rc")
        
        baseOpId = result['id']
        
        op1 = self.authAndCreateOp(baseOpId, baseOpId, 'negative', title = 'op1-', content = 'op')
        
        self.checkAttentions(baseOpId, 0, 1)
        
        op11 = self.authAndCreateOp(baseOpId, op1['id'], 'positive', title = 'op11-', content = 'op')
        
        self.checkAttentions(baseOpId, 0, 2)
        self.checkAttentions(op1['id'], 1, 0)
        
        op111 = self.authAndCreateOp(baseOpId, op11['id'], 'neutral', title = 'op111', content = 'op')
        
        self.checkAttentions(baseOpId, 0, 2)
        self.checkAttentions(op1['id'], 1, 0)
        self.checkAttentions(op11['id'], 0, 0)
        
        self.authAndCreateOp(baseOpId, op111['id'], 'positive', title = 'op1111', content = 'op')
        
        self.checkAttentions(baseOpId, 0, 2)
        self.checkAttentions(op1['id'], 1, 0)
        self.checkAttentions(op11['id'], 0, 0)
        self.checkAttentions(op111['id'], 1, 0)
        
        op1112 = self.authAndCreateOp(baseOpId, op111['id'], 'negative', title = 'op1112', content = 'op')
        
        self.checkAttentions(baseOpId, 0, 2)
        self.checkAttentions(op1['id'], 1, 0)
        self.checkAttentions(op11['id'], 0, 0)
        self.checkAttentions(op111['id'], 1, 1)
        
        self.authAndCreateOp(baseOpId, op1112['id'], 'negative', title = 'op11121', content = 'op')
        self.checkAttentions(baseOpId, 0, 2)
        self.checkAttentions(op1['id'], 1, 0)
        self.checkAttentions(op11['id'], 0, 0)
        self.checkAttentions(op111['id'], 2, 1)
        self.checkAttentions(op1112['id'], 0, 1)
    
    def test_several_negatives(self):
        self.sc.authorize('moderator1', 'test', 'bopin_c')
        
        result = self.sc.createBaseOp("attentions test base", "bla bla bla", "moderators:d sent_default_group:rc")
        baseOpId = result['id']
        
        op1 = self.authAndCreateOp(baseOpId, baseOpId, 'positive', title = 'op1', content = 'op')
        
        op11 = self.authAndCreateOp(baseOpId, op1['id'], 'negative', title = 'op11', content = 'op')
        
        op111 = self.authAndCreateOp(baseOpId, op11['id'], 'negative', title = 'op111', content = 'op')
        
        op1111 = self.authAndCreateOp(baseOpId, op111['id'], 'negative', title = 'op1111', content = 'op')
        
        op11111 = self.authAndCreateOp(baseOpId, op1111['id'], 'negative', title = 'op11111', content = 'op')
        
        self.authAndCreateOp(baseOpId, op11111['id'], 'negative', title = 'op111111', content = 'op')
        
        self.checkAttentions(baseOpId, 3, 3)
        self.checkAttentions(op1['id'], 2, 3)
        self.checkAttentions(op11['id'], 2, 2)
        self.checkAttentions(op111['id'], 1, 2)
        self.checkAttentions(op1111['id'], 1, 1)
        self.checkAttentions(op11111['id'], 0, 1)
    
    def test_create_opinion_with_same_user(self):
        
        self.sc.authorize('moderator1', 'test', 'bopin_c')
        
        result = self.sc.createBaseOp("attentions test base", "bla bla bla", "moderators:d sent_default_group:rc")
        baseOpId = result['id']
        
        op1 = self.authAndCreateOp(baseOpId, baseOpId, 'positive', title = 'op1', content = 'op')
        
        self.sc.authorize('repeated_commenter', 'emptypass', baseOpId + ':rc')
        op11 = self.sc.createOp(op1['id'], 'positive', title = 'op11', content = 'op')
        
        op111 = self.authAndCreateOp(baseOpId, op11['id'], 'positive', title = 'op111', content = 'op')
        
        self.authAndCreateOp(baseOpId, op111['id'], 'positive', title = 'op1111', content = 'op')
        
        self.authAndCreateOp(baseOpId, op111['id'], 'negative', title = 'op1112', content = 'op')
        
        op112 = self.authAndCreateOp(baseOpId, op11['id'], 'negative', title = 'op112', content = 'op')
        
        self.authAndCreateOp(baseOpId, op112['id'], 'positive', title = 'op1121', content = 'op')
        
        self.authAndCreateOp(baseOpId, op112['id'], 'negative', title = 'op1122', content = 'op')
        
        self.checkAttentions(baseOpId, 5, 3)
        self.checkAttentions(op1['id'], 4, 3)
        self.checkAttentions(op11['id'], 3, 3)
        self.checkAttentions(op111['id'], 1, 1)
        self.checkAttentions(op112['id'], 1, 1)
        
        self.sc.authorize('repeated_commenter', 'emptypass', baseOpId + ':rc')
        op12 = self.sc.createOp(op1['id'], 'positive', title = 'op12', content = 'op')
        
        self.checkAttentions(baseOpId, 2, 0)
        self.checkAttentions(op1['id'], 1, 0)
        self.checkAttentions(op11['id'], 3, 3)
        self.checkAttentions(op111['id'], 1, 1)
        self.checkAttentions(op112['id'], 1, 1)
        
        self.authAndCreateOp(baseOpId, op12['id'], 'positive', title = 'op121', content = 'op')
        
        self.checkAttentions(baseOpId, 3, 0)
        self.checkAttentions(op1['id'], 2, 0)
        self.checkAttentions(op12['id'], 1, 0)
        self.checkAttentions(op11['id'], 3, 3)
        self.checkAttentions(op111['id'], 1, 1)
        self.checkAttentions(op112['id'], 1, 1)
        
        self.authAndCreateOp(baseOpId, op112['id'], 'positive', title = 'op1123', content = 'op')
        
        self.checkAttentions(baseOpId, 3, 0)
        self.checkAttentions(op1['id'], 2, 0)
        self.checkAttentions(op12['id'], 1, 0)
        self.checkAttentions(op11['id'], 3, 4)
        self.checkAttentions(op111['id'], 1, 1)
        self.checkAttentions(op112['id'], 2, 1)
        
        allOp = self.sc.getOpSimple(baseOpId, 'most_attended', max_content_length=4)
        print json.dumps(allOp)
        
    def test_get_opinion(self):
        self.sc.authorize('moderator1', 'test', 'bopin_r')
        result = self.sc.viewListOp('all_base_opinions', 'most_attended', access_token = self.sc.accessToken, max_content_length = 2)
        print json.dumps(result)
        page = result['page']
        if len(page):
            opId = page[0]['id']
            self.sc.authorize('moderator1', 'test', opId + ':r')
            allOp = self.sc.getOpSimple(opId, 'most_attended', max_content_length=4)
            print json.dumps(allOp)
            
            allOp = self.sc.getOpSimple(opId, 'most_positive', max_content_length=4)
            print json.dumps(allOp)
    
    def test_create_thumb_only(self):
        self.sc.authorize('moderator1', 'test', 'bopin_c')
        
        with self.assertRaises(HTTPError) as cm:
            self.sc.createBaseOp("", "", "moderators:d sent_default_group:rc")
        self.assertEqual(cm.exception.code, 400)
        
        baseOp = self.sc.createBaseOp("some title", "some content", "moderators:d sent_default_group:rc")
        
        #you cannot have neutral opinion without comment 
        with self.assertRaises(HTTPError) as cm:
            self.sc.createOp(baseOp['id'], 'neutral')
        self.assertEqual(cm.exception.code, 400)
        
        self.sc.createOp(baseOp['id'], 'neutral', title="some base comment")
        
        thumbUp = self.sc.createOp(baseOp['id'], 'positive')
        
        #you cannot comment something which does not contain valuable content
        with self.assertRaises(HTTPError) as cm:
            self.authAndCreateOp(None, thumbUp['id'], 'neutral', title="some base comment")
        self.assertEqual(cm.exception.code, 400)
        
        #you cannot support something that does not contain valuable content
        with self.assertRaises(HTTPError) as cm:
            self.authAndCreateOp(None, thumbUp['id'], 'positive')
        self.assertEqual(cm.exception.code, 400)
    
    def test_move_evaluation_bg4(self):
        self.sc.authorize('moderator1', 'test', 'bopin_c')
        baseOp = self.sc.createBaseOp("test BG op 4", "some content", "moderators:d sent_default_group:rc")
        
        self.authAndCreateOp(baseOp['id'], baseOp['id'], 'negative', title="c-")
        
        check_opinion_tree(self, baseOp['id'], 1)
        
        neutralOp = self.authAndCreateOp(baseOp['id'], baseOp['id'], 'neutral', title="c=")
        
        check_opinion_tree(self, baseOp['id'], 2)
        
        positiveOp = self.authAndCreateOp(baseOp['id'], baseOp['id'], 'positive', title="c+")
        
        check_opinion_tree(self, baseOp['id'], 3)
        
        #now like the positive
        self.authAndCreateOp(baseOp['id'], positiveOp['id'], 'positive')
        
        check_opinion_tree(self, baseOp['id'], 3)
        
        #now with same user like the neutral
        self.sc.createOp(neutralOp['id'], 'positive')
        
        #should not fail
        check_opinion_tree(self, baseOp['id'], 3)
        
        self.sc.createOp(positiveOp['id'], 'positive')
        
        #should not fail
        check_opinion_tree(self, baseOp['id'], 3)
    
    def test_optimizations(self):
        self.sc.authorize('moderator1', 'test', 'bopin_c')
        baseOp = self.sc.createBaseOp("test BG op 4", "some content", "moderators:d sent_default_group:rc")
        
        op1 = self.authAndCreateOp(baseOp['id'], baseOp['id'], 'negative', title="c-")
        
        self.authAndCreateOp(baseOp['id'], op1['id'], 'negative')
        
        self.checkAttentions(baseOp['id'], 1, 1)
        self.checkAttentions(op1['id'], 0, 1)
        
        self.sc.createOp(op1['id'], 'negative')
        
        self.checkAttentions(baseOp['id'], 1, 1)
        self.checkAttentions(op1['id'], 0, 1)
        
        check_opinion_tree(self, baseOp['id'], 1)
        
        self.sc.createOp(op1['id'], 'positive')
        
        self.checkAttentions(baseOp['id'], 0, 2)
        self.checkAttentions(op1['id'], 1, 0)
        
        check_opinion_tree(self, baseOp['id'], 1)
        
        self.sc.createOp(op1['id'], 'positive')
        
        self.checkAttentions(baseOp['id'], 0, 2)
    
    def test_disappearing_title(self):
        self.sc.authorize('moderator1', 'test', 'bopin_c')
        baseOp = self.sc.createBaseOp("test no title", "some content", "moderators:d sent_default_group:rc")
        
        self.authAndCreateOp(baseOp['id'], baseOp['id'], 'positive')
        
        op2 = self.sc.createOp(baseOp['id'], 'positive', title="title")
        
        result_op = self.sc.getOpSimple(op2['id'], 'oldest')
        
        self.assertEqual("title", result_op['title'])
    
    def test_unicode_text(self):
        self.sc.authorize('moderator1', 'test', 'bopin_c')
        baseOp = self.sc.createBaseOp(u"тест", u"някво съдържание", "moderators:d sent_default_group:rc")
        result_op = self.sc.getOpSimple(baseOp['id'], 'oldest')
        
        self.assertEqual(u"тест", result_op['title'])
        
if __name__ == "__main__":
    #import sys;sys.argv = ['', 'Test.testName']
    unittest.main()